package net.spadea.math.fraction.tests;

import static org.junit.Assert.*;

import java.math.BigInteger;

import net.spadea.math.fraction.Fraction;

import org.junit.Test;

public class TestBasicOperations {

	@Test
	public void testGetWhole() {
		
		Fraction frac = new Fraction(1,2,3);
		if ( frac.getWhole().intValue() != 1)
			fail("Not yet implemented");
	}

	@Test
	public void testSetWhole() {
		Fraction frac = new Fraction(1,2,3);
		
		if (frac.getWhole().intValue() != 1)
			fail("Constructor or getWhole() failed.");
		else {
			frac.setWhole(BigInteger.valueOf(5));
			if(frac.getWhole().intValue() != 5) {
				fail("setWhole() failed.");
			}
		}
		
	}

	@Test
	public void testGetNumerator() {
		Fraction frac = new Fraction(1,2,3);
		
		if (frac.getNumerator().intValue() != 2)
			fail("Constructor or getNumerator() failed.");
		
	}

	@Test
	public void testSetNumerator() {
		Fraction frac = new Fraction(1,2,3);
		
		if (frac.getNumerator().intValue() != 2)
			fail("Constructor or getNumerator() failed.");
		else {
			frac.setNumerator(BigInteger.valueOf(5));
			if(frac.getNumerator().intValue() != 5) {
				fail("setNumerator() failed.");
			}
		}
	}

	@Test
	public void testGetDenominator() {
		Fraction frac = new Fraction(1,2,3);
		
		if (frac.getDenominator().intValue() != 3)
			fail("Constructor or getDenominator() failed.");
	}

	@Test
	public void testSetDenominator() {
		Fraction frac = new Fraction(1,2,3);
		
		if (frac.getDenominator().intValue() != 3)
			fail("Constructor or getDenominator() failed.");
		else {
			frac.setDenominator(BigInteger.valueOf(5));
			if(frac.getDenominator().intValue() != 5) {
				fail("setDenominator() failed.");
			}
		}
	}

	@Test
	public void testToMixed() {
		Fraction frac = new Fraction(0,5,3);
		frac.toMixed();
		
		int whole = frac.getWhole().intValue();
		int numerator = frac.getNumerator().intValue();
		int denominator = frac.getDenominator().intValue();
		
		if (whole != 1 || numerator != 2 || denominator != 3 ) {
			fail("toMixed() failed!");
		}
	}

	@Test
	public void testToLowestTerms() {
		Fraction frac = new Fraction(0, 16, 32);
		
		frac.toLowestTerms();
		
		int numerator = frac.getNumerator().intValue();
		int denominator = frac.getDenominator().intValue();
		
		if ( numerator != 1 || denominator != 2) 
			fail("toLowestTerms failed to reduce 16/32 to 1/2!");
		
	}

	@Test
	public void testToImproper() {
		Fraction frac = new Fraction(1,2,3);
		
		frac.toImproper();
		
		int whole = frac.getWhole().intValue();
		int numerator = frac.getNumerator().intValue();
		int denominator = frac.getDenominator().intValue();
		
		if ( whole != 0 || numerator != 5 || denominator != 3) 
			fail("toImproper failed to convert 1 2/3 to 5/3");
		
	}

	@Test
	public void testToReciprocal() {
		Fraction frac = new Fraction(0,2,3);
		
		frac.toReciprocal();
		frac.toImproper();
		
		int whole = frac.getWhole().intValue();
		int numerator = frac.getNumerator().intValue();
		int denominator = frac.getDenominator().intValue();
		
		if ( numerator != 3 || denominator != 2) 
			fail("toReciprocal failed to flip 2/3 to 3/2. Gave: " + frac);
	}

	@Test
	public void testAdd() {
		Fraction frac = new Fraction(1, 1, 3);
		Fraction frac2 = new Fraction(2, 3, 4);
		
		Fraction sum = frac.add(frac2);
		
		int whole = sum.getWhole().intValue();
		int numerator = sum.getNumerator().intValue();
		int denominator = sum.getDenominator().intValue();
		
		if (whole != 4 || numerator != 1 || denominator != 12 ) {
			fail("add() failed! Result: " + frac + " + " + frac2 + " = " + sum);
		}
		
	}

	@Test
	public void testSubtract() {
		Fraction frac = new Fraction(1, 1, 3);
		Fraction frac2 = new Fraction(2, 3, 4);
		
		Fraction difference = frac2.subtract(frac);
		
		int whole = difference.getWhole().intValue();
		int numerator = difference.getNumerator().intValue();
		int denominator = difference.getDenominator().intValue();
		
		if (whole != 1 || numerator != 5 || denominator != 12 ) {
			fail("subtract() failed! Result: " + frac2 + " - " + frac + " = " + difference);
		}
	}

	@Test
	public void testMultiply() {
		Fraction frac = new Fraction(0, 2, 3);
		Fraction frac2 = new Fraction(0, 3, 4);
		
		Fraction product = frac.multiply(frac2);
		
		int whole = product.getWhole().intValue();
		int numerator = product.getNumerator().intValue();
		int denominator = product.getDenominator().intValue();
		
		// Answer = 6/12, which should be reduced to 1/2
		if (whole != 0 || numerator != 1 || denominator != 2 ) {
			fail("multiply() failed! Result: " + frac + " * " + frac2 + " = " + product);
		}
	}

	@Test
	public void testDivide() {
		Fraction frac = new Fraction(0, 2, 3);
		Fraction frac2 = new Fraction(0, 4, 3);
		
		Fraction quotient = frac.divide(frac2);
		
		int whole = quotient.getWhole().intValue();
		int numerator = quotient.getNumerator().intValue();
		int denominator = quotient.getDenominator().intValue();
		
		// Answer = 6/12, which should be reduced to 1/2
		if (whole != 0 || numerator != 1 || denominator != 2 ) {
			fail("divide() failed! Result: " + frac + " / " + frac2 + " = " + quotient);
		}
	}

	@Test
	public void testCompareTo() {
		Fraction frac = new Fraction(1, 2, 3);
		Fraction frac2 = new Fraction(1,1,3);
		
		if (frac.compareTo(frac2) < 0)
			fail("compareTo failed. Thinks 1 2/3 is less than 1 1/3");
		else 
			if(frac.compareTo(frac2) == 0)
				fail("compareTo failed. Thinks 1 2/3 equals 1 1/3");

	}

	@Test
	public void testEqualsFraction() {
		Fraction frac = new Fraction(1, 2, 3);
		Fraction frac2 = new Fraction(1, 1, 3);
		
		if (frac.equals(frac2))
			fail("compareTo failed. Thinks 1 2/3 equals 1 1/3");

	}

	@Test
	public void testClone() {
		Fraction frac = new Fraction(1,2,3);
		Fraction clone = frac.clone();
		

		int whole = clone.getWhole().intValue();
		int numerator = clone.getNumerator().intValue();
		int denominator = clone.getDenominator().intValue();
		
		if(whole != clone.getWhole().intValue() ||
		   numerator != clone.getNumerator().intValue() ||
		   denominator != clone.getDenominator().intValue()
		  )
			fail("Clone was not equal to original!");
		
	}

}
